package com.mar.framecompress;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

public class FrameEncoder {

	private static final int DEFAULT_BUFF_SIZE = 1024;

	private final IEncoder dataEncoder;
	private final IColorEncoder colorEncoder;

	private final ByteBuffer tmpBuffer;

	public FrameEncoder(IEncoder dataEncoder, IColorEncoder colorEncoder) {
		if (colorEncoder.getActualBits() % 8 != 0) {
			throw new IllegalArgumentException(
			"Color encoder should encode data in pieces multiple 8 bits");
		}

		this.dataEncoder = dataEncoder;
		this.colorEncoder = colorEncoder;
		this.tmpBuffer = ByteBuffer.allocate(DEFAULT_BUFF_SIZE);
	}

	public void encodeFrame(Frame frame, ByteBuffer outputBuffer) {
		encodeColorData(frame.getArgbBuffer());
		dataEncoder.encode(tmpBuffer, outputBuffer);	
	}

	private void encodeColorData(IntBuffer argbBuffer) {
		switch (colorEncoder.getActualBits()) {
		case 8:
			while (argbBuffer.hasRemaining()) {
				tmpBuffer.put((byte) colorEncoder.encode(argbBuffer.get()));
			}
			break;

		case 16:
			while (argbBuffer.hasRemaining()) {
				int encodedColor = colorEncoder.encode(argbBuffer.get());
				tmpBuffer.put((byte) encodedColor);
				tmpBuffer.put((byte) (encodedColor >> 8));
			}
			break;

		case 24:
			while (argbBuffer.hasRemaining()) {
				int encodedColor = colorEncoder.encode(argbBuffer.get());
				tmpBuffer.put((byte) encodedColor);
				tmpBuffer.put((byte) (encodedColor >> 8));
				tmpBuffer.put((byte) (encodedColor >> 16));
			}
			break;

		case 32:
			while (argbBuffer.hasRemaining()) {
				int encodedColor = colorEncoder.encode(argbBuffer.get());
				tmpBuffer.put((byte) encodedColor);
				tmpBuffer.put((byte) (encodedColor >> 8));
				tmpBuffer.put((byte) (encodedColor >> 16));
				tmpBuffer.put((byte) (encodedColor >> 24));
			}
			break;
		}
		tmpBuffer.flip();
	}
}
